"use strict";
import * as React from 'react';
import { timeAreaStyles } from "../assets/styles/timeAreaPicker";
import MyText from "./MyText";
import { autoSize, commonStyles } from "../assets/styles/common";
import Line from "./Line";
import Colors from "../assets/styles/Colors";
import MyIcon from "./icon";
import { kAuthorization, SCREEN_WIDTH } from "../constant";
import T from "../utils/T";
import constant from "../utils/constant";
import Request from "../utils/Request";
const { View, Animated, TouchableOpacity, ScrollView, PanResponder, DeviceEventEmitter } = require('react-native');
const { connect } = require('react-redux');
const Collapsible = require('react-native-collapsible').default;
const { DatePicker } = require('antd-mobile');
const moment = require("moment");
const _startMoment = moment({ hour: 8, minute: 0 });
const _now = moment();
const itemWidth = SCREEN_WIDTH / 8;
class TimeAreaPicker extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.stretchTo = (target, change = false, changeState = {}) => {
            Animated.timing(this.state.width, {
                toValue: target,
                duration: 0
            }).start(_ => {
                if (change) {
                    let startIndex = parseInt(this.state.position._value / itemWidth + ''), canBook = true, length = parseInt(target / itemWidth + '');
                    for (let i = 0; i < length; i++) {
                        if (this.state.timeArea.data[startIndex + i] && this.state.timeArea.data[startIndex + i].canPick === false) {
                            canBook = false;
                            break;
                        }
                    }
                    changeState['canBook'] = canBook;
                    this.setState(Object.assign({}, changeState));
                }
            });
        };
        this.moveTo = (target, change = false, changeState = {}) => {
            Animated.timing(this.state.position, {
                toValue: target,
                duration: 0
            }).start(_ => {
                if (change) {
                    let startIndex = parseInt(target / itemWidth + ''), canBook = true, length = parseInt(this.state.width._value / itemWidth + '');
                    for (let i = 0; i < length; i++) {
                        if (this.state.timeArea.data[startIndex + i].canPick === false) {
                            canBook = false;
                            break;
                        }
                    }
                    changeState['canBook'] = canBook;
                    this.setState(Object.assign({}, changeState));
                }
            });
        };
        this.onDragRightPanResponderFinish = (e, gestureState) => {
            this._scrollView.setNativeProps({ scrollEnabled: true });
            const currentPosition = this._dragRightPosition;
            const left = this.state.position._value;
            const width = currentPosition - left;
            const fullWidth = parseInt((width / itemWidth) + '') * itemWidth;
            const ratio = (width - fullWidth) / itemWidth;
            let targetWidth = fullWidth + (ratio > 0.5 ? itemWidth : 0);
            targetWidth = (targetWidth / itemWidth < 0.5) ? itemWidth : targetWidth;
            const selectDuration = parseInt((targetWidth / itemWidth) + '') * 30;
            this._timerAreaGestureState = parseInt(((gestureState.x0 / (SCREEN_WIDTH / 8 * 26)) * 26) + '');
            const change = selectDuration !== this.state.selectDuration;
            this.stretchTo(targetWidth, change, { selectDuration });
            DeviceEventEmitter.emit(constant.noticeKeyOfTimeAreaUnFocus);
        };
        this.onSelectTimeAreaResponderFinish = (e, gestureState) => {
            this._scrollView.setNativeProps({ scrollEnabled: true });
            const ratio = parseInt((this._selectTimeAreaPosition / itemWidth) + '');
            const sidePosition = ratio * itemWidth;
            const offset = this._selectTimeAreaPosition - sidePosition;
            let targetPosition = sidePosition + (offset / itemWidth > 0.5 ? itemWidth : 0);
            targetPosition = targetPosition < 0 ? 0 : targetPosition;
            targetPosition = (targetPosition + this.state.width._value) > itemWidth * 26 ? itemWidth * 26 - this.state.width._value : targetPosition;
            const area = parseInt((targetPosition / itemWidth) + '');
            const hour = 8 + parseInt((area / 2) + '');
            const minute = parseInt((area) + '') % 2 === 0 ? 0 : 30;
            const selectStart = moment({ hour, minute });
            const change = !selectStart.isSame(this.state.selectStart);
            this.moveTo(targetPosition, change, { selectStart });
            DeviceEventEmitter.emit(constant.noticeKeyOfTimeAreaUnFocus);
        };
        this.onSelectTimeAreaResponderMove = ({ nativeEvent: { locationX } }, { dx, moveX }) => {
            this._selectTimeAreaPosition = this._selectTimeAreaOnBeginPosition + dx;
            const area = parseInt((this._selectTimeAreaPosition / itemWidth) + '');
            const hour = 8 + parseInt((area / 2) + '');
            const minute = parseInt((area) + '') % 2 === 0 ? 0 : 30;
            const selectStart = moment({ hour, minute });
            const change = (!selectStart.isSame(this.state.selectStart) && this._selectTimeAreaPosition > 0 && (this._selectTimeAreaPosition + this.state.width._value) < itemWidth * 26);
            this.moveTo(this._selectTimeAreaPosition, change, { selectStart });
        };
        this.onCollapsed = () => {
            this._scrollView.setNativeProps({ scrollEnabled: true });
            DeviceEventEmitter.emit(constant.noticeKeyOfOpenTimeAreaPicker, JSON.stringify(this.props.roomItem));
            this._dragRightPan = PanResponder.create({
                onStartShouldSetPanResponder: (evt) => !this.getCollapsed(),
                onStartShouldSetResponderCapture: (evt) => !this.getCollapsed(),
                onPanResponderGrant: (evt, gestureState) => {
                    this._width = this.state.width._value;
                    this._dragRightOnBeginPosition = this.state.position._value + this._width;
                    this._scrollView.setNativeProps({ scrollEnabled: false });
                },
                onPanResponderTerminate: this.onDragRightPanResponderFinish,
                onPanResponderRelease: this.onDragRightPanResponderFinish,
                onPanResponderMove: (evt, gestureState) => {
                    this._dragRightPosition = this._dragRightOnBeginPosition + gestureState.dx;
                    this.stretchTo(this._width + gestureState.dx);
                }
            });
            this._selectTimeAreaPan = PanResponder.create({
                onStartShouldSetPanResponder: (evt) => !this.getCollapsed(),
                onStartShouldSetResponderCapture: (evt) => !this.getCollapsed(),
                onPanResponderGrant: (evt, gestureState) => {
                    this._selectTimeAreaOnBeginPosition = this.state.position._value;
                    this._scrollView.setNativeProps({ scrollEnabled: false });
                },
                onPanResponderTerminate: this.onSelectTimeAreaResponderFinish,
                onPanResponderRelease: this.onSelectTimeAreaResponderFinish,
                onPanResponderMove: this.onSelectTimeAreaResponderMove
            });
            this.setState({ collapsed: false });
            if (this.props.start)
                return;
            const hour = 8 + parseInt((this._timerAreaGestureState / 2) + '');
            const minute = parseInt((this._timerAreaGestureState) + '') % 2 === 0 ? 0 : 30;
            const selectStart = moment({ hour, minute });
            this.moveTo(this._timerAreaGestureState * itemWidth, true, { selectDuration: 30, selectStart });
        };
        this.onPlusSelectDuration = () => {
            if (this.state.selectDuration < 26 * 30) {
                let selectDuration = this.state.selectDuration + 30;
                const value = this.state.width._value;
                this.stretchTo(value + itemWidth, true, { selectDuration });
                this.onChange(this.state.selectStart, selectDuration);
            }
        };
        this.onReduceSelectDuration = () => {
            if (this.state.selectDuration > 30) {
                const selectDuration = this.state.selectDuration - 30;
                const value = this.state.width._value;
                this.stretchTo(value - itemWidth, true, { selectDuration });
            }
        };
        this.getCollapsed = () => {
            return this.state.collapsed;
        };
        this.getPanGesture = () => {
            if (this.getCollapsed()) {
                return this._tapPan.panHandlers;
            }
            else {
                return null;
            }
        };
        this.getDragRightPan = () => {
            if (!this.getCollapsed()) {
                if (!this._dragRightPan) {
                    this._dragRightPan = PanResponder.create({
                        onStartShouldSetPanResponder: (evt) => !this.getCollapsed(),
                        onStartShouldSetResponderCapture: (evt) => !this.getCollapsed(),
                        onPanResponderGrant: (evt, gestureState) => {
                            this._width = this.state.width._value;
                            this._dragRightOnBeginPosition = this.state.position._value + this._width;
                            this._scrollView.setNativeProps({ scrollEnabled: false });
                            DeviceEventEmitter.emit(constant.noticeKeyOfTimeAreaFocus);
                        },
                        onPanResponderTerminate: this.onDragRightPanResponderFinish,
                        onPanResponderRelease: this.onDragRightPanResponderFinish,
                        onPanResponderMove: (evt, gestureState) => {
                            this._dragRightPosition = this._dragRightOnBeginPosition + gestureState.dx;
                            this.stretchTo(this._width + gestureState.dx);
                        }
                    });
                }
                return Object.assign({}, this._dragRightPan.panHandlers);
            }
            return null;
        };
        this.getSelectTimeAreaPan = () => {
            if (!this.getCollapsed()) {
                if (!this._selectTimeAreaPan) {
                    this._selectTimeAreaPan = PanResponder.create({
                        onStartShouldSetPanResponder: (evt) => {
                            return !this.getCollapsed();
                        },
                        onStartShouldSetResponderCapture: (evt) => {
                            !this.getCollapsed();
                        },
                        onPanResponderGrant: (evt, gestureState) => {
                            this._selectTimeAreaOnBeginPosition = this.state.position._value;
                            this._scrollView.setNativeProps({ scrollEnabled: false });
                            DeviceEventEmitter.emit(constant.noticeKeyOfTimeAreaFocus);
                        },
                        onPanResponderTerminate: this.onSelectTimeAreaResponderFinish,
                        onPanResponderRelease: this.onSelectTimeAreaResponderFinish,
                        onPanResponderMove: this.onSelectTimeAreaResponderMove
                    });
                }
                return Object.assign({}, this._selectTimeAreaPan.panHandlers);
            }
            return null;
        };
        this.onNextStepPress = () => {
            this.props.onNextStepPress({
                start: this.state.selectStart,
                duration: this.state.selectDuration,
                date: this.props.date,
                timeArea: this.state.timeArea
            });
        };
        this.onScroll = ({ nativeEvent: { contentOffset, contentInset, contentSize, layoutMeasurement } }) => {
            this._scrollViewOffSet = contentOffset.x;
        };
        this.showStartDateDicker = () => {
            this.setState({ showStartDateDicker: true });
        };
        this.showEndDateDicker = () => {
            this.setState({ showEndDateDicker: true });
        };
        this.onStartDateDickerDidSelectDate = (date) => {
            let selectStart = moment(date);
            const diff = selectStart.diff(_startMoment);
            let position = 0;
            let full = 0;
            let dot = 0;
            if (diff > 0 && selectStart.isAfter(_startMoment)) {
                const minute = parseInt((diff / 60000) + '');
                full = position = parseInt((minute / 30) + '');
                dot = parseInt((minute % 30) + '');
                position = full + (dot > 15 ? 1 : 0);
            }
            this.moveTo(position * itemWidth);
            selectStart = moment({ hour: 8 + position / 2, minute: position % 2 === 0 ? 0 : 30 });
            this.setState({
                showStartDateDicker: false,
                selectStart
            });
            this.onChange(selectStart, this.state.selectDuration);
        };
        this.onEndDateDickerDidSelectDate = (date) => {
            const selectMomet = moment(date);
            const diff = selectMomet.diff(this.state.selectStart);
            const minute = parseInt((diff / 60000) + '');
            let full = parseInt((minute / 30) + '');
            const dot = parseInt((minute % 30) + '');
            full = full + (dot > 15 ? 1 : 0);
            this.stretchTo(full * itemWidth);
            this.setState({ showEndDateDicker: false, selectDuration: full * 30 });
            this.onChange(this.state.selectStart, full * 30);
        };
        this.hideDateDicker = () => {
            this.setState({ showStartDateDicker: false });
            this.setState({ showEndDateDicker: false });
        };
        this.onChange = (start, duration) => {
        };
        this.upDateRoomBookedInfo = (date) => {
            this.setState({
                loadingRoomInfo: true
            });
            let params = {
                roomId: this.props.roomItem.id,
                date: moment(date).format('YYYY-MM-DD')
            };
            params[kAuthorization] = this.props.auth.token_type + ' ' + this.props.auth.access_token;
            Request.get(Request.getApi().roomBookedInfo, params)
                .then((d) => {
                this.setState({
                    loadingRoomInfo: false
                });
                if (d) {
                    d.map((b) => {
                        let obj = {};
                        obj['startIndex'] = (moment(b.start, 'HH:mm').hour() - 8) * 2 + (moment(b.start, 'HH:mm').minute() >= 30 ? 1 : 0);
                        obj['length'] = parseInt(Math.abs(moment(b.end, 'HH:mm').diff(moment(b.start, 'HH:mm'), 'minute')) / 30 + '');
                        return obj;
                    }).map((flag) => {
                        for (let i = 0; i < flag.length; i++) {
                            this.state.timeArea.data[flag.startIndex + i].canPick = false;
                        }
                    });
                    this.setState({
                        bookedInfo: d,
                        timeArea: this.state.timeArea
                    });
                }
            })
                .catch(e => {
                this.setState({
                    loadingRoomInfo: false
                });
            });
        };
        this.OnChangeReserveDate = (e) => {
            this.upDateRoomBookedInfo(JSON.parse(e));
        };
        this.onNotice = (e) => {
            const roomItem = JSON.parse(e);
            if (roomItem.id !== this.props.roomItem.id) {
                if (!this.getCollapsed()) {
                    this.setState({ collapsed: true, focused: false });
                }
            }
            else {
                this.upDateRoomBookedInfo(this.props.date);
            }
        };
        this._scrollView = {
            setNativeProps: _ => _,
        };
        let duration = 0;
        if (parseInt(props.duration + '') % 30 === 0) {
            duration = props.duration / 30;
        }
        else {
            duration = parseInt((props.duration / 30) + '');
        }
        let position = props.start ? 0 : -SCREEN_WIDTH;
        if (props.start) {
            let diff = props.start.diff(_startMoment);
            if (diff > 0 && props.start.isAfter(_startMoment)) {
                position = parseInt(((diff / 60000) / 30) + '') * itemWidth;
            }
        }
        this.state = {
            focused: false,
            collapsed: props.collapsed,
            width: new Animated.Value(duration * itemWidth),
            position: new Animated.Value(position),
            selectDuration: props.duration,
            selectStart: props.start,
            showStartDateDicker: false,
            showEndDateDicker: false,
            bookedInfo: [],
            timeArea: props.timeArea ? props.timeArea : new TimeAre(moment(props.date)),
            canBook: props.canBook,
            loadingRoomInfo: false
        };
        this.initPanResponder();
    }
    componentWillReceiveProps(nextProps, nextContext) {
        if (moment(this.props.date).format('YYYY-MM-DD') !== moment(nextProps.date).format('YYYY-MM-DD')) {
            const timeArea = new TimeAre(moment(nextProps.date));
            let startIndex = parseInt(this.state.position._value / itemWidth + ''), canBook = true, length = parseInt(this.state.width._value / itemWidth + '');
            for (let i = 0; i < length; i++) {
                if (timeArea.data[startIndex + i].canPick === false) {
                    canBook = false;
                    break;
                }
            }
            this.setState({
                date: nextProps.date,
                timeArea,
                canBook
            });
            this.upDateRoomBookedInfo(nextProps.date);
        }
    }
    componentDidMount() {
        DeviceEventEmitter.addListener(constant.noticeKeyOfOpenTimeAreaPicker, this.onNotice);
        DeviceEventEmitter.addListener(constant.noticeKeyOfChangeReserveDate, this.OnChangeReserveDate);
        if (!this.getCollapsed()) {
            this._scrollView.setNativeProps({ scrollEnabled: true });
        }
        const offset = this.state.position._value;
        if (offset > 0) {
            this._scrollView.scrollTo({ x: offset, animated: true });
        }
    }
    ;
    componentWillUnmount() {
        DeviceEventEmitter.removeListener(constant.noticeKeyOfOpenTimeAreaPicker);
        DeviceEventEmitter.removeListener(constant.noticeKeyOfChangeReserveDate);
    }
    initPanResponder() {
        this._tapPan = PanResponder.create({
            onStartShouldSetPanResponder: (evt) => true,
            onStartShouldSetResponderCapture: (evt) => true,
            onPanResponderGrant: (evt, gestureState) => {
                if (this.getCollapsed()) {
                    this._timerAreaGestureState = parseInt(((gestureState.x0 / (SCREEN_WIDTH / 8 * 26)) * 26) + '');
                    this.setState({
                        focused: true,
                    });
                    setTimeout(() => {
                        if (!this.state.focused) {
                            this.onCollapsed();
                        }
                    }, 100);
                }
            },
            onPanResponderRelease: () => {
                this.setState({
                    focused: false,
                });
            }
        });
    }
    render() {
        let minEndDate = this.state.selectStart;
        minEndDate = moment(minEndDate).add(30, 'minute');
        return (<View>
                
                {this.props.canPickDate ? <View style={timeAreaStyles.selectTimeBtnContainer}>
                    <TouchableOpacity style={timeAreaStyles.selectTimeBtn} disabled={this.getCollapsed()} onPress={this.showStartDateDicker}>
                        <MyIcon name={'icon-shijian'} size={autoSize(15)} color={Colors.SubTitle}/>
                        <MyText color={Colors.Title} fontSize={15} style={{ marginLeft: 10 }}>{this.state.selectStart.format('HH:mm')}</MyText>
                    </TouchableOpacity>
                    <View style={timeAreaStyles.selectTimeSeparate}/>
                    <TouchableOpacity style={timeAreaStyles.selectTimeBtn} disabled={this.getCollapsed()} onPress={this.showEndDateDicker}>
                        <MyText color={Colors.SubTitle} fontSize={15} style={{ marginRight: 10 }}>{T('end')}:</MyText>
                        <MyText color={Colors.Active} fontSize={15}>{moment(this.state.selectStart).add(this.state.selectDuration, 'minute').format('HH:mm')}</MyText>
                    </TouchableOpacity>
                </View> : null}
                <View style={timeAreaStyles.col}>

                    
                    <View style={[timeAreaStyles.timeAxis]} {...this.getPanGesture()}>
                        <ScrollView horizontal onScroll={this.onScroll} scrollEventThrottle={60} scrollEnabled={false} ref={ref => this._scrollView = ref} contentContainerStyle={[{ backgroundColor: Colors.Background }, commonStyles.relative]} showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false}>
                            {this.state.timeArea.data.map((item, index) => {
            return <TimeAreaItem timeItem={item} lastOne={index === this.state.timeArea.data.length} enable={item.canPick} begin={index % 2 === 0} key={index}/>;
        })}
                            <Animated.View {...this.getSelectTimeAreaPan()} style={[commonStyles.absolute, timeAreaStyles.pickerArea,
            {
                width: this.state.width,
                left: this.state.position,
                backgroundColor: this.state.canBook ? Colors.Active : Colors.CanNotPick
            }]}>
                                <View style={[commonStyles.flexRow, commonStyles.flex1, timeAreaStyles.dragFlagContainer]}>
                                    <View {...this.getDragRightPan()} style={timeAreaStyles.dragFlagRight}/>
                                </View>
                            </Animated.View>
                        </ScrollView>
                        {this.state.loadingRoomInfo ? <View style={timeAreaStyles.loadingRoomInfo}>
                            <MyText color={Colors.White} style={{ marginTop: autoSize(25) }}>更新房间预定信息中...</MyText>
                        </View> : null}
                    </View>

                    <Collapsible collapsed={this.state.collapsed} align="center">
                        <View style={[timeAreaStyles.actionBar, { height: autoSize(this.props.haveNextStep ? 102 : 50), }]}>
                            <View style={[commonStyles.flex1, commonStyles.flexRow, timeAreaStyles.actionsContainer]}>
                                <TouchableOpacity onPress={this.onReduceSelectDuration}>
                                    <MyIcon name='icon-jian' color={Colors.Active}/>
                                </TouchableOpacity>
                                <View style={[commonStyles.flex1, timeAreaStyles.actionsTextContainer]}>
                                    <MyText>{`${this.state.selectDuration} ${T('minute')}`}</MyText>
                                    <MyText>{`${this.state.selectStart.format('HH:mm')}-${moment(this.state.selectStart).add(this.state.selectDuration, 'minute').format('HH:mm')}`}</MyText>
                                </View>
                                <TouchableOpacity onPress={this.onPlusSelectDuration}>
                                    <MyIcon name='icon-iconfont707' color={Colors.Active}/>
                                </TouchableOpacity>
                            </View>
                            {this.props.haveNextStep ?
            <TouchableOpacity style={[timeAreaStyles.actionButton, commonStyles.centerVH,
                { backgroundColor: this.state.canBook ? Colors.Active : Colors.Disabled }]} disabled={!this.state.canBook} onPress={this.onNextStepPress}>
                                    <MyText color={Colors.White}>{T(this.state.canBook ? 'Next step' : 'Please select correct time')}</MyText>
                                </TouchableOpacity> : null}

                        </View>
                    </Collapsible>
                </View>
                
                <DatePicker visible={this.state.showStartDateDicker} mode="time" value={_startMoment.toDate()} minDate={_now.toDate()} onDismiss={this.hideDateDicker} onOk={this.onStartDateDickerDidSelectDate}/>
                
                <DatePicker visible={this.state.showEndDateDicker} mode="time" minDate={minEndDate.toDate()} value={_startMoment.toDate()} onDismiss={this.hideDateDicker} onOk={this.onEndDateDickerDidSelectDate}/>
            </View>);
    }
}
TimeAreaPicker.defaultProps = {
    collapsed: false,
    haveNextStep: true,
    start: _startMoment,
    duration: 30,
    canPickDate: false,
    date: moment(),
    onNextStepPress: () => {
    },
    onChange: () => {
    }
};
class TimeAreaItem extends React.Component {
    render() {
        return (<View style={[commonStyles.relative, {
                height: '100%',
                width: itemWidth,
                backgroundColor: Colors.White
            }]}>
                <View style={[{ height: autoSize(25), display: 'flex', justifyContent: 'flex-end', paddingLeft: 2 }]}>
                    {this.props.timeItem.showLabel ? <MyText fontSize={10}>{this.props.timeItem.label}</MyText> : null}
                </View>

                <View style={[commonStyles.flex1, { backgroundColor: this.props.enable ? Colors.White : Colors.UnAvailable }]}>

                </View>


                <Line width={1} height={this.props.lastOne ? autoSize(75) : (this.props.begin ? autoSize(75) : autoSize(60))} style={[commonStyles.absolute, { left: 0, bottom: 0 }]} color={'#E0E0E0'}/>
            </View>);
    }
}
TimeAreaItem.defaultProps = {
    enable: false,
    begin: false
};
class TimeItem {
    constructor(value, label, showLabel, canPick = true) {
        this.value = value;
        this.label = label;
        this.showLabel = showLabel;
        this.canPick = canPick;
    }
}
class TimeAre {
    constructor(date = moment()) {
        let time = 8;
        let isToday = date.format('YYY-MM-DD') === moment().format('YYY-MM-DD');
        this.data = new Array(26).fill('').map((_, i) => {
            const item = new TimeItem(time, `${time}时`, i % 2 === 0);
            if (isToday) {
                const t1 = moment({
                    hour: parseInt(time * 10 + '') / 10,
                    minute: parseInt(time * 10 + '') % 10 / 10 * 60
                });
                const t2 = moment({ hour: date.hour(), minute: date.minute() });
                item.canPick = !t1.isBefore(t2);
            }
            else {
                item.canPick = true;
            }
            time += 0.5;
            return item;
        });
    }
}
export default connect(({ auth }) => ({ auth }))(TimeAreaPicker);
